package com.bjtime.hprinter.lib

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.os.Environment
import java.io.*


/**
 * Create by YiBei on 2019/6/17
 * Description :Bitmap图像处理工具类
 */
object BitmapUtil{

    //保存图片
    fun saveMyBitmap(mBitmap: Bitmap):String {
        val fileName = (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
                .toString()
                + File.separator
                + "AndroidBitmap_" + System.currentTimeMillis() + ".jpg")
        val file = File(fileName)
        if (!file.parentFile.exists()) {
            file.parentFile.mkdir()
        }
        var fOut: FileOutputStream? = null
        try {
            fOut = FileOutputStream(file)
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
        }

        try {
            if (null != fOut) {
                mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut)
                fOut.flush()
                fOut.close()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return fileName
    }

    //旋转图片
    fun rotateMyBitmap(bmp: Bitmap):String {
        //*****旋转一下
        val matrix = Matrix()
        matrix.postRotate(270f)

        val bitmap = Bitmap.createBitmap(bmp.width, bmp.height, Bitmap.Config.RGB_565)

        val nbmp2 = Bitmap.createBitmap(bmp, 0, 0, bmp.width, bmp.height, matrix, true)

        return saveMyBitmap(compressImage(nbmp2)!!)

        //*******显示一下
        // imgview.setImageBitmap(nbmp2)

    }


    //压缩图片
    fun compressImage(image: Bitmap): Bitmap? {
        val baos = ByteArrayOutputStream()
        // 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        image.compress(Bitmap.CompressFormat.JPEG, 50, baos)
        // 把压缩后的数据baos存放到ByteArrayInputStream中
        val isBm = ByteArrayInputStream(baos.toByteArray())
        // 把ByteArrayInputStream数据生成图片
        return BitmapFactory.decodeStream(isBm, null, null)
    }


    fun zoomBitmap(bitmap: Bitmap, width: Int, height: Int): Bitmap {
        val w = bitmap.width
        val h = bitmap.height
        val matrix = Matrix()
        val scaleWidth = width.toFloat() / w
        val scaleHeight = height.toFloat() / h
        matrix.postScale(scaleWidth, scaleHeight)
        return Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true)
    }

    fun compress(old:Bitmap):Bitmap{
        var bitmap: Bitmap? = null
        val filePath= saveMyBitmap(old)
        val opts = BitmapFactory.Options()
        opts.inJustDecodeBounds = true
        BitmapFactory.decodeFile(filePath, opts)

        opts.inSampleSize = computeSampleSize(opts, -1, 280 * 280)
        opts.inJustDecodeBounds = false

        try {
            bitmap = BitmapFactory.decodeFile(filePath, opts)
        } catch (e: java.lang.Exception) { // TODO: handle exception
        }
        return bitmap!!
    }

    fun computeSampleSize(
        options: BitmapFactory.Options,
        minSideLength: Int,
        maxNumOfPixels: Int
    ): Int {
        val initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels)
        var roundedSize: Int
        if (initialSize <= 8) {
            roundedSize = 1
            while (roundedSize < initialSize) {
                roundedSize = roundedSize shl 1
            }
        } else {
            roundedSize = (initialSize + 7) / 8 * 8
        }
        return roundedSize
    }

    private fun computeInitialSampleSize(
        options: BitmapFactory.Options,
        minSideLength: Int,
        maxNumOfPixels: Int
    ): Int {
        val w = options.outWidth.toDouble()
        val h = options.outHeight.toDouble()
        val lowerBound =
            if (maxNumOfPixels == -1) 2 else Math.ceil(Math.sqrt(w * h / maxNumOfPixels)).toInt()
        val upperBound = if (minSideLength == -1) 240 else Math.min(
            Math.floor(w / minSideLength),
            Math.floor(h / minSideLength)
        ).toInt()
        if (upperBound < lowerBound) { // return the larger one when there is no overlapping zone.
            return lowerBound
        }
        return if (maxNumOfPixels == -1 && minSideLength == -1) {
            1
        } else if (minSideLength == -1) {
            lowerBound
        } else {
            upperBound
        }
    }

}